﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Asol.Reporting.Support.Components;

namespace Asol.Reporting.Green.Forms
{
    public partial class LoginForm : Form
    {
        #region Konstrukce
        public LoginForm()
        {
            InitializeComponent();
            this.Init();
        }
        private void Init()
        {
            // this.BackColor = Color.FromArgb(255, 254, 254, 255);
            // this.TransparencyKey = Color.FromArgb(255, 254, 254, 255);

            this._Fms = new Support.Components.FormMoveSupport(this, this._BackImage, 
                this._ServerLabel, this._ServerInfo, this._ProfileLabel, this._ProfileInfo,
                this._ClassLabel, this._ReportLabel, this._DescriptionLabel);
            this._BackImage.Dock = DockStyle.Fill;

            this.CancelButton = this._CloseButton;

            this.InitSetting();
            this.InitClasses();
        }
        Asol.Reporting.Support.Components.FormMoveSupport _Fms;
        #endregion
        #region Settings
        /// <summary>
        /// Inicializuje comba _ServerCombo a _ProfileCombo
        /// </summary>
        protected void InitSetting()
        {
            this._Settings = App.Settings;
            this._ServerCombo.FillItems(this._Settings.ServerList, this._Settings.ActiveServer);
            this._ProfileCombo.FillItems(this._Settings.ProfileList, this._Settings.ActiveProfile);
            this._ServerCombo.ComboEditAction += new ComboEditEventHandler(_ServerCombo_ComboEditAction);
            this._ProfileCombo.ComboEditAction += new ComboEditEventHandler(_ProfileCombo_ComboEditAction);
            this._ShowSettingData();
            this._ShowSettingControls(false);
        }
        private void _ShowSettingData()
        {
            this._ServerInfo.Text = this._Settings.ActiveServer.ServerName;
            this._ProfileInfo.Text = this._Settings.ActiveProfile.ProfileName;
        }
        /// <summary>
        /// Zobrazí pro patřičné controly Enabled a Visible podle požadavku "settings":
        /// true = dovolí editovat připojení, false = vybírá třídu a reporty
        /// </summary>
        /// <param name="dbSettingMode"></param>
        private void _ShowSettingControls(bool dbSettingMode)
        {
            this._ServerInfo.Visible = !dbSettingMode;
            this._ProfileInfo.Visible = !dbSettingMode;
            this._ServerCombo.Visible = dbSettingMode;
            this._ProfileCombo.Visible = dbSettingMode;
            this._ChangeButton.Text = (dbSettingMode ? "dokončeno" : "změnit");

            this._ClassCombo.Enabled = !dbSettingMode;
            this._ReportCombo.Enabled = !dbSettingMode;

            this._OpenButtonRefresh();

            if (dbSettingMode)
                this._ServerCombo.Focus();
            else
                this._ClassCombo.Focus();

            this._DbSettingMode = dbSettingMode;
        }
        /// <summary>
        /// Ošetří editaci v combu _ServerCombo
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void _ServerCombo_ComboEditAction(object sender, ComboEditEventArgs args)
        {
            this._Settings.ServerEditAction(sender, args);
            if (args.Action == ComboEditActionType.Select && args.Commit)
                this._ProfileComboFill();
        }
        /// <summary>
        /// Ošetří editaci v combu _ProfileCombo
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void _ProfileCombo_ComboEditAction(object sender, ComboEditEventArgs args)
        {
            this._Settings.ProfileEditAction(sender, args);
            if (args.Action == ComboEditActionType.Select && args.Commit)
                this._ClassComboLoad();
        }
        /// <summary>
        /// Naplní combo _ProfileCombo daty z this._Settings: ProfileList a ActiveProfile.
        /// </summary>
        private void _ProfileComboFill()
        {
            this._ProfileCombo.FillItems(this._Settings.ProfileList, this._Settings.ActiveProfile);
        }
        private Asol.Reporting.Green.Settings _Settings;
        #endregion
        #region Seznam tříd a reportů
        private void InitClasses()
        {
            this._ClassCombo.Enter += this._ClassesComboEnter;
            this._ClassCombo.SelectedIndexChanged += this._ClassesComboSelectedIndexChanged;
            this._ClassCombo.MinimumTextLengthForWhisperFill = 1;
            this._ClassCombo.MaximumComboItemsForDropDown = 25;
            this._ReportCombo.Enter += this._ReportComboEnter;
            this._ReportCombo.SelectedIndexChanged += this._ReportComboSelectedIndexChanged;
            this._ReportCombo.TextChanged += new EventHandler(_ReportComboTextChanged);
            this._ReportCombo.MinimumTextLengthForWhisperFill = 0;
            this._ReportCombo.MaximumComboItemsForDropDown = 16;
            this._LoadPresetFromRegister();
            this._ComboSetFromPreset();
        }
        /// <summary>
        /// Vyprázdní combo Class, Templates podle zadání
        /// </summary>
        /// <param name="classes"></param>
        /// <param name="reports"></param>
        private void _DataComboClear(bool classes, bool reports)
        {
            if (classes)
            {
                this._ClassCombo.Items.Clear();
                this._ClassCombo.SelectedIndex = -1;
                this._ClassCombo.Text = "";
                this._SelectedClassNumber = null;
            }
            if (reports)
            {
                this._ReportCombo.Items.Clear();
                this._ReportCombo.SelectedIndex = -1;
                this._ReportCombo.Text = "";
                this._SelectedTemplate = null;
            }
            this._OpenButtonRefresh();
        }
        /// <summary>
        /// Po vstupu do combo Classes se ověří shoda/neshoda connect stringu pro data načtená v Combo proti aktuálnímu, 
        /// případně se data znovu načtou
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _ClassesComboEnter(object sender, EventArgs e)
        {
            string conn = App.Settings.ActiveConnectStringBuilder.ConnectionString;
            if (this._ClassCombo.Tag is string && (string)this._ClassCombo.Tag == conn) return;
            this._ClassComboLoad();
        }
        /// <summary>
        /// Načte do comba _ClassCombo seznam tříd
        /// </summary>
        private void _ClassComboLoad()
        {
            this._DataComboClear(true, true);

            string conn = App.Settings.ActiveConnectStringBuilder.ConnectionString;
            string sql = "SELECT cislo_tridy, nazev_tridy + ' (' + cast(cislo_tridy as varchar) + ')' as trida FROM lcs.nis_tridy ORDER BY trida";
            Asol.Reporting.Support.Data.Table table = DbConnect.LoadTable(sql);
            this._ClassList = table.Rows.Convert(row => new DComboItem(row[0].ValueInteger, row[1].ToString(), row)).ToList();
            this._ClassCombo.WhisperList = this._ClassList;
            this._ClassCombo.Tag = conn;
        }
        /// <summary>
        /// Po změně hodnoty v nabídce tříd se určí vybrané číslo třídy
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _ClassesComboSelectedIndexChanged(object sender, EventArgs e)
        {
            this._SelectedClassNumber = null;

            DComboItem item = this._ClassCombo.SelectedItem as DComboItem;
            if (item == null) return;
            if (!(item.ID is long)) return;          // item.ID pochází z _ClassComboLoad(): row[0].ValueInteger, což je formálně Int64 = long

            this._SelectedClassNumber = (Int32)((Int64)item.ID);
            this._DataComboClear(false, true);
        }
        /// <summary>
        /// Po vstupu do combo Reporty ověří jeho správné naplnění pro aktuální ConnectString a číslo třídy this._SelectedClassNumber, pokud není aktuální tak znovu naplní
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _ReportComboEnter(object sender, EventArgs e)
        {
            Int32? classNum = this._SelectedClassNumber;
            string conn = App.Settings.ActiveConnectStringBuilder.ConnectionString + ">" + classNum.ToString();
            if (this._ReportCombo.Tag is string && (string)this._ReportCombo.Tag == conn) return;
            this._ReportComboLoad(classNum);
        }
        /// <summary>
        /// Načte pro danou třídu její reporty do this._ReportWhisperList
        /// </summary>
        /// <param name="classNum"></param>
        private void _ReportComboLoad(int? classNum)
        {
            this._DataComboClear(false, true);

            string conn = App.Settings.ActiveConnectStringBuilder.ConnectionString + ">" + classNum.ToString();
            if (classNum.HasValue)
            {
                this._TemplateList = TemplateInfo.LoadTemplates(classNum.Value);
                this._ReportCombo.WhisperList = this._TemplateList;
                this._ReportCombo.MinimumTextLengthForWhisperFill = 0;
                this._ReportCombo.Tag = conn;
            }
            else
            {
                this._ReportCombo.WhisperList = new List<DComboItem>();
                this._ReportCombo.Tag = "";
            }
        }
        /// <summary>
        /// Po změně textu v comu reportů (například Delete): zruší výběr šablony
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _ReportComboTextChanged(object sender, EventArgs e)
        {
            this._SelectedTemplate = null;
            this._OpenButton.Enabled = false;
        }
        /// <summary>
        /// Po výběru šablony tu vybranou šablonu vloží do this._SelectedTemplate, a zajistí zobrazení jejích detailních informací
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _ReportComboSelectedIndexChanged(object sender, EventArgs e)
        {
            this._SelectedTemplate = null;

            TemplateInfo templateInfo = this._ReportCombo.SelectedItem as TemplateInfo;
            if (templateInfo == null) return;
            this._SelectedTemplate = templateInfo;
            this._SelectedTemplateShow();

            this._OpenButtonRefresh();
        }
        /// <summary>
        /// Zobrazí detaily aktuálně vybrané šablony, po změně výběru (i na NULL)
        /// </summary>
        private void _SelectedTemplateShow()
        {
            TemplateInfo templateInfo = this._SelectedTemplate;
            bool ex = (templateInfo != null);
            string description = (ex ? templateInfo.Description : "");
            this._DescriptionLabel.Text = description;
        }
        /// <summary>
        /// Refreshuje button "otevřít"
        /// </summary>
        private void _OpenButtonRefresh()
        {
            this._OpenButton.Enabled = (!this._DbSettingMode && this._SelectedTemplate != null);
        }
        private List<DComboItem> _ClassList;
        private List<TemplateInfo> _TemplateList;
        private Int32? _SelectedClassNumber;
        private TemplateInfo _SelectedTemplate;
        private bool _DbSettingMode;
        #endregion
        #region Registry (Load a Save)
        /// <summary>
        /// Načte z registru hodnoty do this._SelectedClassNumber a this._SelectedReportNumber.
        /// </summary>
        private void _LoadPresetFromRegister()
        {
            this._PresetClassNumber = this._Int32NLoadFromRegister("Green.Last", "ClassNumber");
            if (this._PresetClassNumber.HasValue)
                this._PresetTemplateNumber = this._Int32NLoadFromRegister("Green.Last", "ReportNumber");
            else
                this._PresetTemplateNumber = null;
        }
        /// <summary>
        /// Z registru načte a vrátí hodnotu Int32? z dané složky a hodnoty.
        /// </summary>
        /// <param name="folder"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        private int? _Int32NLoadFromRegister(string folder, string name)
        {
            Int32 value;
            if (!Asol.Reporting.Support.Register.TryGetValue<Int32>(folder, name, out value)) return (Int32?)null;
            if (value == 0) return (Int32?)null;
            return (Int32?)value;
        }
        /// <summary>
        /// Uloží aktuální hodnoty z this._PresetClassNumber a this._PresetTemplateNumber do registru.
        /// </summary>
        private void _SavePresetToRegister()
        {
            Asol.Reporting.Support.Register.Set("Green.Last", "ClassNumber", (this._PresetClassNumber.HasValue ? this._PresetClassNumber.Value : 0));
            Asol.Reporting.Support.Register.Set("Green.Last", "ReportNumber", (this._PresetTemplateNumber.HasValue ? this._PresetTemplateNumber.Value : 0));
            Asol.Reporting.Support.Register.Save();
        }
        /// <summary>
        /// Pokusí se přednastavit combo _ClassCombo a _ReportCombo na hodnoty uložené v this._PresetClassNumber a this._PresetTemplateNumber.
        /// </summary>
        private void _ComboSetFromPreset()
        {
            this._DataComboClear(true, true);

            this._ClassComboLoad();

            if (!this._PresetClassNumber.HasValue) return;
            DComboItem classItem = this._ClassList.FirstOrDefault(c => c.ID.CompareTo((Int64)(this._PresetClassNumber.Value)) == 0);
            this._ClassCombo.WhisperSelectedItem = classItem;

            if (classItem == null) return;
            this._ReportComboLoad(this._PresetClassNumber.Value);

            if (!this._PresetTemplateNumber.HasValue) return;
            TemplateInfo templateInfo = this._TemplateList.FirstOrDefault(c => c.TemplateNumber == this._PresetTemplateNumber.Value);
            this._ReportCombo.WhisperSelectedItem = templateInfo;
        }
        /// <summary>
        /// Aktuální hodnoty vybrané třídy a šablony vloží do 
        /// </summary>
        private void _ComboStoreToPreset()
        {
            this._PresetClassNumber = this._SelectedClassNumber;
            this._PresetTemplateNumber = (this._SelectedTemplate != null ? (Int32?)this._SelectedTemplate.TemplateNumber : (Int32?)null);
        }
        private Int32? _PresetClassNumber;
        private Int32? _PresetTemplateNumber;
        #endregion
        #region Buttony
        private void _ChangeButton_Click(object sender, EventArgs e)
        {
            bool dbSettingMode = !this._DbSettingMode;
            if (dbSettingMode)
            {
                this._ComboStoreToPreset();
                this._DataComboClear(true, true);
            }
            else
            {
                this._ComboSetFromPreset();
            }

            this._ShowSettingControls(dbSettingMode);
        }
        private void _OpenButton_Click(object sender, EventArgs e)
        {
            if (this._SelectedTemplate != null)
            {
                this._ComboStoreToPreset();
                this._SavePresetToRegister();
                this.Hide();
                Asol.Reporting.Support.Assistant.Run(delegate { App.ReportEdit(this._SelectedTemplate); });
                this.Show();
                // this.Close();
                // App.ReportEdit(this._SelectedTemplate);
                // Asol.Reporting.Editor
            }
        }
        private void _CloseButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        #endregion
    }
}
